/**
 * Created With IntelliJ IDEA
 * Description:牛客网：BM82 买卖股票的最好时机(三)
 * <a href="https://www.nowcoder.com/practice/4892d3ff304a4880b7a89ba01f48daf9?tpId=295&tqId=1073487&ru=/exam/oj&qru=/ta/format-top101/question-ranking&sourceUrl=%2Fexam%2Foj">...</a>
 * User: DELL
 * Data: 2022-11-15
 * Time: 23:07
 */

//动态规划经典题目，具体分析过多，详情见牛客网中的java官网讲解
import java.util.*;

public class Solution {
    public int maxProfit (int[] prices) {
        //题目中规定prices数组不为空
        int len = prices.length;
        //dp[i][0]表示到第i天为止没有买过股票的最大收益
        //dp[i][1]表示到第i天为止买过一次股票还没有卖出的最大收益
        //dp[i][2]表示到第i天为止买过一次也卖出过一次股票的最大收益
        //dp[i][3]表示到第i天为止买过两次只卖出过一次股票的最大收益
        //dp[i][4]表示到第i天为止买过两次同时也买出过两次股票的最大收益
        int[][] dp = new int[len][5];
        //初始化dp[0]为最小值
        Arrays.fill(dp[0],-10000);
        //初始第0天的数据
        dp[0][0] = 0;
        dp[0][1] = -prices[0];
        for (int i = 1; i < len; i++) {
            dp[i][0] = dp[i - 1][0];
            dp[i][1] = Math.max(dp[i - 1][1],dp[i][0] - prices[i]);
            dp[i][2] = Math.max(dp[i - 1][2],dp[i - 1][1] + prices[i]);
            dp[i][3] = Math.max(dp[i - 1][3],dp[i - 1][2] - prices[i]);
            dp[i][4] = Math.max(dp[i - 1][4],dp[i - 1][3] + prices[i]);
        }
        //返回值应为没有买过、买卖一次和买卖两次能获取到的最大利润的最大值
        return Math.max(dp[len - 1][0],Math.max(dp[len - 1][2],dp[len - 1][4]));
    }
}
